﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SilentVoice.Models;

namespace SilentVoice.Data
{
    public class EventManagement
    {

        public Event CreateEvent(Event svEvent)
        {
            using (NotesContext context = new NotesContext())
            {
                Event addedEvent = context.Events.Add(svEvent);
                context.SaveChanges();
                
                return addedEvent;
            }
        }

        public Event UpdateEvent(Event svEvent)
        {
            using (NotesContext context = new NotesContext())
            {
                Event updatedEvent = context.Events.Attach(svEvent);
                context.Entry(svEvent).State = System.Data.EntityState.Modified;
                context.SaveChanges();
                //TODO: what happens if event did not exist?
                return updatedEvent;
            }
        }

        public Event GetEvent(int eventId)
        {
            using (NotesContext context = new NotesContext())
            {
                Event svEvent = context.Events.SingleOrDefault(x => x.Id == eventId);

                return svEvent;
            }
        }

        public Event DeleteEvent(Event svEvent)
        {
            using (NotesContext context = new NotesContext())
            {
                Event toDelete = context.Events.Single(x => x.Id == svEvent.Id);

                toDelete = context.Events.Remove(toDelete);
                context.SaveChanges();
                return toDelete;
            }
        }

        public ScratchPad CreateScratchPad(ScratchPad scratchPad)
        {
            using (NotesContext context = new NotesContext())
            {
                ScratchPad addedScratchPad = context.ScratchPads.Add(scratchPad);
                context.SaveChanges();

                return addedScratchPad;
            }
        }

        public ScratchPad UpdateScratchPad(ScratchPad scratchPad)
        {
            using (NotesContext context = new NotesContext())
            {
                ScratchPad updatedScratchPad = context.ScratchPads.Attach(scratchPad);
                context.Entry(scratchPad).State = System.Data.EntityState.Modified;
                context.SaveChanges();

                return updatedScratchPad;
            }
        }

        public ScratchPad GetScratchPad(int scratchId)
        {
            using (NotesContext context = new NotesContext())
            {
                ScratchPad scratchPad = context.ScratchPads.SingleOrDefault(x => x.Id == scratchId);

                return scratchPad;
            }
        }

        public ScratchPad DeleteScratchPad(ScratchPad scratchPad)
        {
            using (NotesContext context = new NotesContext())
            {
                ScratchPad scratchPadToDelete = context.ScratchPads.Single(x => x.Id == scratchPad.Id);

                scratchPadToDelete = context.ScratchPads.Remove(scratchPadToDelete);
                context.SaveChanges();
                return scratchPadToDelete;
            }
        }

        public ScratchPad GetScratchPadForEvent(User owner, Event svEvent)
        {
            using (NotesContext context = new NotesContext())
            {
                ScratchPad scratchPad = context.ScratchPads
                    .SingleOrDefault(x => x.OwnerId == owner.Id && x.EventId == svEvent.Id);

                return scratchPad;
            }
        }

        public ICollection<Group> GetEventAllowedGroups(Event svEvent)
        {
            using (NotesContext context = new NotesContext())
            {
                Event targetEvent = context.Events.SingleOrDefault(x => x.Id == svEvent.Id);

                if (targetEvent == null)
                {
                    throw new ArgumentException(
                        String.Format("Event with id {0} does not exist", svEvent.Id), "svEvent");
                }

                return targetEvent.AllowedGroups;
            }
        }

        public ICollection<Group> AllowGroup(Event svEvent, Group group)
        {
            using (NotesContext context = new NotesContext())
            {
                Event targetEvent = context.Events.SingleOrDefault(x => x.Id == svEvent.Id);

                if (targetEvent == null)
                {
                    throw new ArgumentException(
                        String.Format("Event with id {0} does not exist", svEvent.Id), "svEvent");
                }

                Group targetGroup = context.Groups.SingleOrDefault(x => x.Id == group.Id);
                
                if (targetGroup == null)
                {
                    throw new ArgumentException(
                        String.Format("Group with id {0} does not exist", group.Id), "group");
                }

                if (targetEvent.AllowedGroups.Contains(targetGroup))
                {
                    throw new ArgumentException("Event already allows group");
                }

                targetEvent.AllowedGroups.Add(targetGroup);
                context.SaveChanges();

                return targetEvent.AllowedGroups;
            }
        }

        public ICollection<Group> DenyGroup(Event svEvent, Group group)
        {
            using (NotesContext context = new NotesContext())
            {
                Event targetEvent = context.Events.SingleOrDefault(x => x.Id == svEvent.Id);

                if (targetEvent == null)
                {
                    throw new ArgumentException(
                        String.Format("Event with id {0} does not exist", svEvent.Id), "svEvent");
                }

                Group targetGroup = context.Groups.SingleOrDefault(x => x.Id == group.Id);

                if (targetGroup == null)
                {
                    throw new ArgumentException(
                        String.Format("Group with id {0} does not exist", group.Id), "group");
                }

                if (!targetEvent.AllowedGroups.Contains(targetGroup))
                {
                    throw new ArgumentException("Event does not already allow group");
                }


                targetEvent.AllowedGroups.Remove(targetGroup);
                context.SaveChanges();

                return targetEvent.AllowedGroups;
            }
        }
    }
}
